package com.lottery.game.runner.v2;

import com.alibaba.fastjson.JSONObject;
import com.lottery.game.common.constants.GameConstants;
import com.lottery.game.common.utils.UUIDUtils;
import com.lottery.game.core.modules.entity.game.GameRoom;
import com.lottery.game.core.modules.entity.user.SpecialOdds;
import com.lottery.game.core.modules.entity.user.UserBlncDetail;
import com.lottery.game.core.modules.service.app.BetService;
import com.lottery.game.core.modules.service.app.WebsocketMessageService;
import com.lottery.game.core.utils.BetUtils;
import com.lottery.game.core.utils.ResultCode;
import com.lottery.game.runner.v2.utils.DataUtil;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;

/**
 * 替换com.runshang.apps.cloudgame.runner.PushResultBean
 * @author Administrator
 *
 */
public class LotteryDrawRunner extends Thread{

	private String expect;
	private String betType;
	private String currentIssue;
	private BetService betService;
	private List<GameRoom>  roomList;
	private GamblingClosuresExecutor gcExecutor;
	private WebsocketMessageService websocketMessageService;

	public LotteryDrawRunner(
			GamblingClosuresExecutor gcExecutor,
			BetService betService,
			String expect,
			String betType,
			String currentIssue,
			List<GameRoom> roomList) {
		this.gcExecutor = gcExecutor;
		this.betService = betService;
        this.expect = expect;
        this.betType = betType;
        this.currentIssue = currentIssue;
        this.roomList = roomList;
    }

	public LotteryDrawRunner(
			GamblingClosuresExecutor gcExecutor,
			BetService betService,
			String expect,
			String betType,
			String currentIssue,
			List<GameRoom> roomList,
			WebsocketMessageService websocketMessageService) {
		this.gcExecutor = gcExecutor;
		this.betService = betService;
        this.expect = expect;
        this.betType = betType;
        this.currentIssue = currentIssue;
        this.roomList = roomList;
        this.websocketMessageService = websocketMessageService;
    }

	public void run() {
		// lotteryTime秒后，进行开奖

		// 获取游戏结果
		Map<String, String> resultBet = DataUtil.getResultBet(expect, betType, betService);
		// 开奖失败 记录到数据库
		if (StringUtils.isEmpty(resultBet.get("status")) || ResultCode.ERROR.equals(resultBet.get("status"))) {
			betService.updateGameIssueStatus(GameConstants.GameIssueStatus_Error, currentIssue, "开奖失败");
			Map<String, String> map = new HashMap<String, String>();
			map.put("expect", expect);
			map.put("status", "-1");
			map.put("content", "开奖失败");
			gcExecutor.initParams(roomList, JSONObject.toJSONString(map));
			gcExecutor.execute();
			return;
		} else {
			// 通过 开奖期号 获取 游戏场次列表
			List<Map<String, Object>> gameMapList = betService.getGamelistByIssue(currentIssue);

			StringBuffer resultSb = new StringBuffer();
			Iterator<Entry<String, String>> it = resultBet.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, String> entity = it.next();
				if (!"resultStr".equals(entity.getKey()) && !"firstValue".equals(entity.getKey())
						&& !"secondValue".equals(entity.getKey()) && !"thirdValue".equals(entity.getKey())
						&& !"status".equals(entity.getKey()) && !"sumValue".equals(entity.getKey())) {
					resultSb.append(entity.getKey());
					resultSb.append("|");
				}
			}
			// note存储开奖结果数字 1|2|3
			String note = resultBet.get("resultStr");
			betService.updateGameIssueResult(GameConstants.GameIssueStatus_Close, currentIssue, resultSb.toString(),
					note);

			// 获取开奖结果值
			Integer sumVaule = Integer.parseInt(resultBet.get("sumValue"));

			List<UserBlncDetail> blncChangeList = new ArrayList<>();
			// 对每一场游戏分别计算
			for (Map<String, Object> map : gameMapList) {
				String roomId = (String) map.get("roomId");
				String gameId = (String) map.get("id");
				// 通过游戏场次id 获取到所有参加游戏的人，和押注数据
				List<Map<String, Object>> userBetList = betService.getUserListByGameid(gameId);
				// 获取房间赔率
				Map<String, Object> oddMap = betService.getOddbyRoomNumber(roomId);

				// 获取特殊赔率
				SpecialOdds querySpecialOdds = new SpecialOdds();
				querySpecialOdds.setRoomnumber(roomId);
				SpecialOdds specialOdds = betService.querySpecialOdds(querySpecialOdds);
				for (Map<String, Object> userBet : userBetList) {
					// 通过游戏场次id 获取到所有参加游戏的人，和押注数据
					String userId = userBet.get("game_user_id").toString();
					String gameBetId = userBet.get("id").toString();
					String userBetStr = userBet.get("betStr").toString();

					String descStr = null;
					if (note != null) {
						descStr = "开出" + note.replace("|", "+") + "=" + sumVaule;
					} else {
						descStr = "无法获取开奖结果";
					}

					GameRoom tmpRoom = betService.queryRoomByBetId(gameBetId);
					if (specialOdds != null) {
						// 判断开奖结果是否是13_14
						if (specialOdds.getSpecialSumList().contains(sumVaule)) {
							oddMap = BetUtils.fixOddMapByUserBet(oddMap, specialOdds, userBet);
							descStr = descStr + "使用1314特殊赔率";
						}
						// 如果房间开启了特殊赔率配置
						if (tmpRoom != null && GameConstants.Str_ONE.equals(tmpRoom.getUseComOdds())) {
							// 且开出的是豹子顺子对子
							if (BetUtils.isBaoziShunziDuizi(resultBet)) {
								oddMap = BetUtils.fixBaseOddMapByBaoziShunziDuizi(oddMap, specialOdds);
								if (BetUtils.isBaseAndCom(userBetStr)) {
									descStr = descStr + "使用豹子顺子对子特殊赔率";
								}
							}
						}
					}

					BigDecimal resultValue = BetUtils.getResultMoney(oddMap, resultBet, userBet);
					resultValue = resultValue.setScale(2,BigDecimal.ROUND_HALF_DOWN);
					if (resultValue.compareTo(BigDecimal.ZERO) != 0) {
						// 保证每个用户只生成一个userBlncDetail
						UserBlncDetail userBlncDetail = new UserBlncDetail();
						// 多条数据累加起来
						userBlncDetail.setId(UUIDUtils.randomUUID());
						userBlncDetail.setBetType(GameConstants.BlanceChangeType_Bonus);
						userBlncDetail.setGameId(gameId);
						userBlncDetail.setUserId(userId);
						userBlncDetail.setChange(String.valueOf(resultValue));
						userBlncDetail.setChangeAmt(resultValue);
						userBlncDetail.setGameBetId(gameBetId);

						StringBuffer sb = new StringBuffer();
						if (tmpRoom != null) {
							// 游戏类型
							sb.append(tmpRoom.getName());
						}
						sb.append("第");
						sb.append(expect);
						sb.append("期");
						sb.append("注单[");
						sb.append(userBet.get("betStr"));
						sb.append("|");
						sb.append(userBet.get("totleAmt"));
						sb.append("]派彩");
						sb.append(descStr);
						String changeReason = sb.toString();

						userBlncDetail.setChangeReason(changeReason);
						blncChangeList.add(userBlncDetail);
					}
				}
			}
			betService.saveBetChange(currentIssue, blncChangeList);
			Map<String, String> map = new HashMap<String, String>();
			map.put("expect", expect);
			map.put("status", "2");
			map.put("content", note);
			gcExecutor.initParams(roomList, JSONObject.toJSONString(map), websocketMessageService, GameConstants.GAME_STATUS_LOTTERY_DRAW);
			gcExecutor.execute();
		}

	}

}
